package lemna.top.chunyu.batch.step8;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.sql.DataSource;

import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepScope;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.database.JdbcPagingItemReader;
import org.springframework.batch.item.database.Order;
import org.springframework.batch.item.database.support.MySqlPagingQueryProvider;
import org.springframework.batch.item.file.transform.BeanWrapperFieldExtractor;
import org.springframework.batch.item.file.transform.FormatterLineAggregator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;

import lemna.top.chunyu.batch.config.ChunYunConfig;
import lemna.top.chunyu.batch.config.Constants;
import lemna.top.chunyu.batch.step4.domain.CommPaymentStatement;
import lemna.top.chunyu.utils.DateUtil;

@Configuration
public class Step8Config {

	@Autowired
	ChunYunConfig config;

	@Autowired
	Resource step8File;

	@Autowired
	ItemReader<CommPaymentStatement> step8Reader;

	@Autowired
	Step8ItemProcessor step8ItemProcessor;

	@Autowired
	private DataSource dataSource;

	@Autowired
	private Step8Callback step8Callback;

	@Autowired
	public StepBuilderFactory stepBuilderFactory;

	@StepScope
	@Bean(name = "step8Reader")
	protected ItemReader<CommPaymentStatement> reader(@Value("#{jobParameters[date]}") Date date) throws Exception {

		JdbcPagingItemReader<CommPaymentStatement> reader = new JdbcPagingItemReader<CommPaymentStatement>();
		reader.setDataSource(dataSource);
		MySqlPagingQueryProvider queryProvider = queryProvider(date);
		reader.setQueryProvider(queryProvider);
		reader.setRowMapper(

				(rs, rowNum) -> CommPaymentStatement.builder().serialNumber(rowNum)
						.merchantNo(rs.getString("merchant_no")).inAccountType(rs.getInt("in_account_type"))
						.inAccountNo(rs.getString("in_account_no")).inAccountName(rs.getString("in_account_name"))
						.liquidationAmount(rs.getDouble("amount")).currency(rs.getString("currency"))
						.liquidationBankNo(rs.getString("liquidation_bank_no"))
						.liquidationMerchantNo(rs.getString("liquidation_merchant_no")).build()

		);
		reader.setPageSize(10);
		reader.afterPropertiesSet();
		reader.setSaveState(true);

		return reader;
	}


	private MySqlPagingQueryProvider queryProvider(Date date) {
		String startTime = Constants.sdf1.format(date);
		String endTime = Constants.sdf1.format(DateUtil.getNextDayZeroTime(date));
		MySqlPagingQueryProvider queryProvider = new MySqlPagingQueryProvider();
		queryProvider.setSelectClause("SELECT 	merchant_no  ,in_account_no ,in_account_name, in_account_type ,SUM(order_amount)-SUM(refund_amount) amount,SUM(service_charge_rate) fee,currency ,liquidation_bank_no ,liquidation_merchant_no");
		queryProvider.setFromClause("FROM chun_yu_payment_statement  ");
		queryProvider.setWhereClause("WHERE in_account_type=3 and create_time > str_to_date('"+startTime+" 00:00:00', '%Y-%m-%d %H:%i:%s') and create_time < str_to_date('"+endTime+" 00:00:00', '%Y-%m-%d %H:%i:%s')");
		queryProvider.setGroupClause("GROUP BY merchant_no  ,in_account_no ,in_account_name, in_account_type ,currency ,liquidation_bank_no ,liquidation_merchant_no ");
		Map<String, Order> sortKeys = new HashMap<String, Order>();
		sortKeys.put("in_account_type", Order.ASCENDING);
		sortKeys.put("liquidation_merchant_no", Order.ASCENDING);
		queryProvider.setSortKeys(sortKeys);
		return queryProvider;
	}

	
	public ItemWriter<CommPaymentStatement> writer() {
		CountFlatFileItemWriter<CommPaymentStatement> writer = new CountFlatFileItemWriter<CommPaymentStatement>();
		writer.setResource(step8File);
		BeanWrapperFieldExtractor<CommPaymentStatement> fieldExtractor = new BeanWrapperFieldExtractor<CommPaymentStatement>();
		fieldExtractor.setNames(new String[] { "liquidationMerchantNo", "inAccountName", "liquidationAmount",
				"createTime", "transactionSummary", "postscript" });

		FormatterLineAggregator<CommPaymentStatement> lineAggregator = new FormatterLineAggregator<CommPaymentStatement>();
		lineAggregator.setFieldExtractor(fieldExtractor);
		lineAggregator.setFormat("%40s %s %10.2f %s %-32s %s");

		writer.setLineAggregator(lineAggregator);
		writer.setEncoding("GBK");
		writer.setFooterCallback(step8Callback);
		writer.setHeaderCallback(step8Callback);

		return writer;
	}

	@Bean
	@StepScope
	protected Resource step8File(@Value("#{jobParameters[date]}") Date date) {

		String dateParam = Constants.sdf2.format(date);
		String filePath = config.getOutputFilePath() + "smzf.zfxt" + dateParam ;//smzf.zfxtYYYYMMDD
		return new FileSystemResource(filePath);
	}

	@Bean(name = "step8")
	public Step step8() throws Exception {
		return stepBuilderFactory.get("step8").<CommPaymentStatement, CommPaymentStatement>chunk(5).reader(step8Reader)
				.processor(step8ItemProcessor).writer(writer()).build();
	}
}
